import geopandas as gpd
from libpysal import graph
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.colors import LogNorm
from matplotlib_scalebar.scalebar import ScaleBar
import pandas as pd
import contextily as cx
signatures = gpd.read_parquet("../../urbangrammar_samba/spatial_signatures/signatures/signatures_combined_levels_orig.pq")
signatures = gpd.read_file("spatial_signatures_GB.gpkg")
signatures
| id | code | type | geometry | |
|---|---|---|---|---|
| 0 | 0_COA | COA | Countryside agriculture | POLYGON ((62220.000 798500.000, 62110.000 7985... |
| 1 | 1_COA | COA | Countryside agriculture | POLYGON ((63507.682 796515.169, 63471.097 7965... |
| 2 | 2_COA | COA | Countryside agriculture | POLYGON ((65953.174 802246.172, 65950.620 8022... |
| 3 | 3_COA | COA | Countryside agriculture | POLYGON ((67297.740 803435.800, 67220.289 8034... |
| 4 | 4_COA | COA | Countryside agriculture | POLYGON ((75760.000 852670.000, 75700.000 8527... |
| ... | ... | ... | ... | ... |
| 96699 | 96699_OUT | OUT | outlier | POLYGON ((323321.005 463795.416, 323319.842 46... |
| 96700 | 96700_OUT | OUT | outlier | POLYGON ((325929.840 1008792.061, 325927.377 1... |
| 96701 | 96701_OUT | OUT | outlier | POLYGON ((337804.770 1013422.583, 337800.122 1... |
| 96702 | 96702_OUT | OUT | outlier | POLYGON ((422304.270 1147826.990, 422296.000 1... |
| 96703 | 96703_OUT | OUT | outlier | POLYGON ((525396.260 439215.480, 525360.920 43... |
96704 rows × 4 columns
signatures.code.unique()
array(['COA', 'ACS', 'OPS', 'WIC', 'WAL', 'GRQ', 'URB', 'DIS', 'DRN',
'CRN', 'DUN', 'LOU', 'DIU', 'REU', 'OUT', 'MEU', 'HDU'],
dtype=object)
# drop an outlier island
signatures = signatures.drop(96691)
signatures_urban = signatures[~signatures.code.isin(["OUT", "COA", "URB", "WIC"])].copy()
signatures_urban
| id | code | type | geometry | |
|---|---|---|---|---|
| 10882 | 10882_ACS | ACS | Accessible suburbia | POLYGON ((143345.668 932691.413, 143345.418 93... |
| 10883 | 10883_ACS | ACS | Accessible suburbia | POLYGON ((151573.910 30042.750, 151571.029 300... |
| 10884 | 10884_ACS | ACS | Accessible suburbia | POLYGON ((151697.494 29760.709, 151650.000 297... |
| 10885 | 10885_ACS | ACS | Accessible suburbia | POLYGON ((162909.562 26425.073, 162911.932 264... |
| 10886 | 10886_ACS | ACS | Accessible suburbia | POLYGON ((164091.320 40526.696, 164093.601 405... |
| ... | ... | ... | ... | ... |
| 96687 | 96687_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528602.732 181135.450, 528572.630 18... |
| 96688 | 96688_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528643.907 181217.443, 528638.400 18... |
| 96689 | 96689_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528734.582 181316.822, 528732.783 18... |
| 96690 | 96690_HDU | HDU | Hyper concentrated urbanity | POLYGON ((530336.433 181039.755, 530336.117 18... |
| 96691 | 96691_HDU | HDU | Hyper concentrated urbanity | POLYGON ((581275.000 184964.000, 581431.000 18... |
68957 rows × 4 columns
%%time
contiguity = graph.Graph.build_fuzzy_contiguity(signatures_urban, buffer=1)
CPU times: user 2min 16s, sys: 2.21 s, total: 2min 18s
Wall time: 2min 18s
%%time
signatures_urban["settlement"] = contiguity.component_labels
CPU times: user 16.2 ms, sys: 0 ns, total: 16.2 ms
Wall time: 15.6 ms
types = {
"0_0": "Countryside agriculture",
"1_0": "Accessible suburbia",
"3_0": "Open sprawl",
"4_0": "Wild countryside",
"5_0": "Warehouse/Park land",
"6_0": "Gridded residential quarters",
"7_0": "Urban buffer",
"8_0": "Disconnected suburbia",
"2_0": "Dense residential neighbourhoods",
"2_1": "Connected residential neighbourhoods",
"2_2": "Dense urban neighbourhoods",
"9_0": "Local urbanity",
"9_1": "Concentrated urbanity",
"9_2": "Regional urbanity",
"9_4": "Metropolitan urbanity",
"9_5": "Hyper concentrated urbanity",
}
signatures_urban["signature_type"] = signatures_urban["signature_type"].map(types)
signatures_urban.settlement.max()
9436
signatures_urban["area"] = signatures_urban.area
grouper = signatures_urban.groupby(["settlement", "type"])
areas = grouper["area"].sum().unstack().fillna(0)
areas
| type | Accessible suburbia | Concentrated urbanity | Connected residential neighbourhoods | Dense residential neighbourhoods | Dense urban neighbourhoods | Disconnected suburbia | Gridded residential quarters | Hyper concentrated urbanity | Local urbanity | Metropolitan urbanity | Open sprawl | Regional urbanity | Warehouse/Park land |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| settlement | |||||||||||||
| 0 | 98432.753668 | 0.0 | 658585.378043 | 82103.007472 | 16858.821454 | 3.867427e+04 | 194436.499973 | 0.0 | 0.0 | 0.000000 | 2.443473e+05 | 0.0 | 392625.177314 |
| 1 | 39159.397355 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 4.303130e+03 | 0.000000 | 0.0 | 0.0 | 0.000000 | 0.000000e+00 | 0.0 | 0.000000 |
| 2 | 1714.392324 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 0.000000 | 7.653142e+02 | 0.0 | 0.000000 |
| 3 | 194126.224307 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 1.116033e+06 | 245226.403996 | 0.0 | 0.0 | 0.000000 | 1.727041e+06 | 0.0 | 0.000000 |
| 4 | 98.243984 | 0.0 | 14951.756016 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 0.000000 | 0.000000e+00 | 0.0 | 0.000000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 9432 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 3069.922515 | 0.000000e+00 | 0.0 | 0.000000 |
| 9433 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 6332.353514 | 0.000000e+00 | 0.0 | 0.000000 |
| 9434 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 563.416847 | 0.000000e+00 | 0.0 | 0.000000 |
| 9435 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 0.0 | 0.0 | 6822.794200 | 0.000000e+00 | 0.0 | 0.000000 |
| 9436 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000e+00 | 0.000000 | 987539.5 | 0.0 | 0.000000 | 0.000000e+00 | 0.0 | 0.000000 |
9437 rows × 13 columns
order = [
'Warehouse/Park land', 'Open sprawl', 'Disconnected suburbia',
'Accessible suburbia', 'Connected residential neighbourhoods',
'Dense residential neighbourhoods', 'Gridded residential quarters',
'Dense urban neighbourhoods', 'Local urbanity', 'Regional urbanity',
'Metropolitan urbanity', 'Concentrated urbanity',
'Hyper concentrated urbanity'
]
order.reverse()
areas_sorted = areas.sort_values(order, ascending=False)[order]
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.iloc[:200].T, norm=LogNorm())
<Axes: xlabel='settlement', ylabel='type'>
areas["total"] = areas.sum(axis=1)
areas.sort_values("total")
| type | Accessible suburbia | Concentrated urbanity | Connected residential neighbourhoods | Dense residential neighbourhoods | Dense urban neighbourhoods | Disconnected suburbia | Gridded residential quarters | Hyper concentrated urbanity | Local urbanity | Metropolitan urbanity | Open sprawl | Regional urbanity | Warehouse/Park land | total |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| settlement | ||||||||||||||
| 3981 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.598476e-04 | 0.000000e+00 | 0.000000e+00 | 1.598476e-04 |
| 5126 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 5.270652e-03 | 0.000000e+00 | 0.000000e+00 | 5.270652e-03 |
| 6706 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.706335e-02 | 0.000000e+00 | 0.000000e+00 | 1.706335e-02 |
| 8593 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 5.482056e-01 | 5.482056e-01 |
| 3588 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 5.982074e-01 | 0.000000e+00 | 0.000000e+00 | 5.982074e-01 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 984 | 8.444854e+07 | 0.000000e+00 | 1.337555e+07 | 3.137510e+07 | 2.479331e+07 | 1.552982e+07 | 2.332107e+06 | 0.000000e+00 | 6.522618e+06 | 1.001744e+05 | 2.786930e+08 | 1.905346e+06 | 1.668628e+07 | 4.757619e+08 |
| 1006 | 1.173756e+07 | 0.000000e+00 | 3.097936e+07 | 5.928168e+07 | 3.574174e+07 | 1.610781e+07 | 3.138634e+06 | 0.000000e+00 | 8.388703e+06 | 0.000000e+00 | 2.054715e+08 | 1.589767e+06 | 2.301844e+08 | 6.026212e+08 |
| 876 | 6.251046e+07 | 0.000000e+00 | 4.149977e+07 | 4.842811e+07 | 2.758493e+07 | 5.417000e+07 | 1.721331e+05 | 0.000000e+00 | 5.745378e+06 | 1.075760e+06 | 1.447718e+08 | 2.806010e+06 | 3.386026e+08 | 7.273669e+08 |
| 407 | 1.885914e+08 | 0.000000e+00 | 8.382661e+07 | 1.443043e+08 | 5.427237e+07 | 3.735568e+07 | 3.914361e+07 | 0.000000e+00 | 7.917305e+06 | 5.156702e+05 | 5.668694e+08 | 3.950296e+06 | 2.810701e+08 | 1.407817e+09 |
| 1845 | 2.132323e+08 | 7.884144e+06 | 1.364017e+08 | 2.235081e+08 | 2.201192e+08 | 8.389185e+07 | 6.699935e+06 | 1.306332e+06 | 1.155779e+08 | 1.321113e+07 | 2.989552e+08 | 3.960246e+07 | 3.819127e+08 | 1.742303e+09 |
9437 rows × 14 columns
areas["total"][areas["total"]<areas["total"].quantile(.75)].plot.hist(bins=150)
<Axes: ylabel='Frequency'>
areas["total"].quantile(.25)
534.3932255090165
areas["total"].median()
1345.9874175296875
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.T, norm=LogNorm())
<Axes: xlabel='settlement', ylabel='type'>
placenames = gpd.read_parquet("place.parquet")
%%time
joined = placenames.sjoin(signatures_urban[["geometry", "settlement"]])
CPU times: user 3.14 s, sys: 0 ns, total: 3.14 s
Wall time: 3.14 s
signatures_urban
| id | code | type | geometry | settlement | area | |
|---|---|---|---|---|---|---|
| 10882 | 10882_ACS | ACS | Accessible suburbia | POLYGON ((143345.668 932691.413, 143345.418 93... | 0 | 9.843275e+04 |
| 10883 | 10883_ACS | ACS | Accessible suburbia | POLYGON ((151573.910 30042.750, 151571.029 300... | 1 | 2.597607e+03 |
| 10884 | 10884_ACS | ACS | Accessible suburbia | POLYGON ((151697.494 29760.709, 151650.000 297... | 1 | 3.656179e+04 |
| 10885 | 10885_ACS | ACS | Accessible suburbia | POLYGON ((162909.562 26425.073, 162911.932 264... | 2 | 1.714392e+03 |
| 10886 | 10886_ACS | ACS | Accessible suburbia | POLYGON ((164091.320 40526.696, 164093.601 405... | 3 | 1.941262e+05 |
| ... | ... | ... | ... | ... | ... | ... |
| 96687 | 96687_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528602.732 181135.450, 528572.630 18... | 1845 | 1.797907e+03 |
| 96688 | 96688_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528643.907 181217.443, 528638.400 18... | 1845 | 1.271663e+06 |
| 96689 | 96689_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528734.582 181316.822, 528732.783 18... | 1845 | 1.872188e+03 |
| 96690 | 96690_HDU | HDU | Hyper concentrated urbanity | POLYGON ((530336.433 181039.755, 530336.117 18... | 1845 | 2.767724e+03 |
| 96691 | 96691_HDU | HDU | Hyper concentrated urbanity | POLYGON ((581275.000 184964.000, 581431.000 18... | 9436 | 9.875395e+05 |
68957 rows × 6 columns
with_names = signatures_urban[signatures_urban.settlement.isin(joined.settlement)]
with_names.settlement.nunique()
1206
no_names = signatures_urban[~signatures_urban.settlement.isin(joined.settlement)]
no_names.settlement
10883 1
10884 1
10885 2
10887 4
10889 6
...
96594 9432
96647 9433
96648 9434
96658 9435
96691 9436
Name: settlement, Length: 10436, dtype: int32
grouper = with_names.groupby(["settlement", "type"])
areas = grouper["area"].sum().unstack().fillna(0)
areas_sorted = areas.sort_values(order, ascending=False)[order]
joined
| local_type | geometry | name1 | index_right | settlement | |
|---|---|---|---|---|---|
| 2023027 | Suburban Area | POINT (418095.000 185406.000) | Nythe | 73480 | 1021 |
| 2049081 | Suburban Area | POINT (417576.000 184893.000) | Park North | 73480 | 1021 |
| 2023028 | Suburban Area | POINT (292127.000 90785.000) | Marsh Barton | 46382 | 285 |
| 2023029 | Suburban Area | POINT (295991.000 91247.000) | Clyst Heath | 23788 | 285 |
| 2040633 | Suburban Area | POINT (294268.000 91766.000) | St Loye's | 23788 | 285 |
| ... | ... | ... | ... | ... | ... |
| 2287377 | Suburban Area | POINT (430095.000 581544.000) | Malvin's Close | 30755 | 1006 |
| 2288413 | Other Settlement | POINT (395461.000 395566.000) | The Railway Sidings | 87974 | 407 |
| 2288557 | Other Settlement | POINT (206144.000 67004.000) | Town End | 21978 | 25 |
| 2288563 | Other Settlement | POINT (465287.000 103797.000) | Vicarage Row | 58015 | 1508 |
| 2288564 | Other Settlement | POINT (465332.000 103793.000) | St Francis Court | 58015 | 1508 |
10561 rows × 5 columns
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.iloc[:200].T, norm=LogNorm())
<Axes: xlabel='settlement', ylabel='type'>
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.T, norm=LogNorm())
<Axes: xlabel='settlement', ylabel='type'>
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.T, norm=LogNorm(), cmap="Blues")
<Axes: xlabel='settlement', ylabel='type'>
import urbangrammar_graphics as ugg
from matplotlib.colors import LinearSegmentedColormap
ugg.COLORS
[(0.19921875, 0.203125, 0.1953125),
(0.23046875, 0.4296875, 0.55078125),
(0.73828125, 0.35546875, 0.30859375),
(0.5625, 0.640625, 0.4921875),
(0.9375, 0.78125, 0.34375),
(0.58203125, 0.3984375, 0.4296875)]
cmap = LinearSegmentedColormap.from_list("ugg", [ugg.COLORS[4], ugg.COLORS[3]])
cmap
ugg
under
bad
over
areas_sorted
| type | Hyper concentrated urbanity | Concentrated urbanity | Metropolitan urbanity | Regional urbanity | Local urbanity | Dense urban neighbourhoods | Gridded residential quarters | Dense residential neighbourhoods | Connected residential neighbourhoods | Accessible suburbia | Disconnected suburbia | Open sprawl | Warehouse/Park land |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| settlement | |||||||||||||
| 1845 | 1.306332e+06 | 7.884144e+06 | 1.321113e+07 | 3.960246e+07 | 1.155779e+08 | 2.201192e+08 | 6.699935e+06 | 2.235081e+08 | 1.364017e+08 | 2.132323e+08 | 8.389185e+07 | 2.989552e+08 | 3.819127e+08 |
| 876 | 0.000000e+00 | 0.000000e+00 | 1.075760e+06 | 2.806010e+06 | 5.745378e+06 | 2.758493e+07 | 1.721331e+05 | 4.842811e+07 | 4.149977e+07 | 6.251046e+07 | 5.417000e+07 | 1.447718e+08 | 3.386026e+08 |
| 389 | 0.000000e+00 | 0.000000e+00 | 6.359560e+05 | 7.521293e+06 | 7.460783e+06 | 9.309406e+06 | 1.394896e+06 | 2.096403e+07 | 1.544039e+07 | 2.041219e+07 | 8.596605e+05 | 3.194950e+07 | 1.814534e+07 |
| 89 | 0.000000e+00 | 0.000000e+00 | 6.071265e+05 | 6.881265e+06 | 1.262601e+07 | 1.710456e+07 | 1.253209e+06 | 3.929345e+07 | 4.141944e+07 | 7.314527e+07 | 3.987755e+06 | 1.679558e+08 | 6.047482e+07 |
| 407 | 0.000000e+00 | 0.000000e+00 | 5.156702e+05 | 3.950296e+06 | 7.917305e+06 | 5.427237e+07 | 3.914361e+07 | 1.443043e+08 | 8.382661e+07 | 1.885914e+08 | 3.735568e+07 | 5.668694e+08 | 2.810701e+08 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8150 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.662141e+04 |
| 7967 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.577238e+04 |
| 9059 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.555250e+04 |
| 8161 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.293481e+04 |
| 8136 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.137823e+03 |
1206 rows × 13 columns
plt.subplots(figsize=(32, 8))
sns.heatmap(data=areas_sorted.T, norm=LogNorm(), cmap="cividis_r")
<Axes: xlabel='settlement', ylabel='type'>
placenames
| local_type | geometry | name1 | |
|---|---|---|---|
| 2023027 | Suburban Area | POINT (418095.000 185406.000) | Nythe |
| 2023028 | Suburban Area | POINT (292127.000 90785.000) | Marsh Barton |
| 2023029 | Suburban Area | POINT (295991.000 91247.000) | Clyst Heath |
| 2023030 | Suburban Area | POINT (233883.000 84586.000) | Kensey Valley Meadow |
| 2023031 | Suburban Area | POINT (293538.000 93365.000) | Polsloe |
| ... | ... | ... | ... |
| 2289904 | Other Settlement | POINT (199430.000 907051.000) | Garadheancal |
| 2289905 | Other Settlement | POINT (636776.000 151377.000) | Wingfield Place |
| 2289906 | Suburban Area | POINT (480934.000 263680.000) | Blackthorn |
| 2289907 | Hamlet | POINT (140772.000 799096.000) | Raonapoll |
| 2289908 | Suburban Area | POINT (249437.000 628134.000) | Hillhead Heights |
43209 rows × 3 columns
with_names
| id | code | type | geometry | settlement | area | |
|---|---|---|---|---|---|---|
| 10882 | 10882_ACS | ACS | Accessible suburbia | POLYGON ((143345.668 932691.413, 143345.418 93... | 0 | 9.843275e+04 |
| 10886 | 10886_ACS | ACS | Accessible suburbia | POLYGON ((164091.320 40526.696, 164093.601 405... | 3 | 1.941262e+05 |
| 10888 | 10888_ACS | ACS | Accessible suburbia | POLYGON ((167653.791 43194.946, 167654.353 431... | 5 | 9.879056e+03 |
| 10893 | 10893_ACS | ACS | Accessible suburbia | POLYGON ((170174.747 41387.203, 170172.782 413... | 8 | 1.610704e+05 |
| 10895 | 10895_ACS | ACS | Accessible suburbia | POLYGON ((175356.122 54184.967, 175365.952 541... | 10 | 6.876061e+03 |
| ... | ... | ... | ... | ... | ... | ... |
| 96686 | 96686_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528530.170 181095.720, 528544.720 18... | 1845 | 2.823163e+04 |
| 96687 | 96687_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528602.732 181135.450, 528572.630 18... | 1845 | 1.797907e+03 |
| 96688 | 96688_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528643.907 181217.443, 528638.400 18... | 1845 | 1.271663e+06 |
| 96689 | 96689_HDU | HDU | Hyper concentrated urbanity | POLYGON ((528734.582 181316.822, 528732.783 18... | 1845 | 1.872188e+03 |
| 96690 | 96690_HDU | HDU | Hyper concentrated urbanity | POLYGON ((530336.433 181039.755, 530336.117 18... | 1845 | 2.767724e+03 |
58521 rows × 6 columns
placenames.local_type.unique()
array(['Suburban Area', 'Hamlet', 'Village', 'Other Settlement', 'Town',
'City'], dtype=object)
with_names.groupby("settlement")["type"].nunique().value_counts() / with_names.settlement.nunique()
type
2 0.285240
3 0.173300
1 0.145108
4 0.117745
5 0.068823
6 0.064677
7 0.050580
8 0.040630
9 0.033167
10 0.011609
11 0.008292
13 0.000829
Name: count, dtype: float64
%%time
settlement_boundaries = with_names[["geometry", "settlement"]].dissolve("settlement")
CPU times: user 1min 28s, sys: 33.3 ms, total: 1min 28s
Wall time: 1min 28s
names = []
for poly in settlement_boundaries.geometry:
names_in = placenames.iloc[placenames.sindex.query(poly, predicate="contains")]
if names_in.shape[0] == 1:
names.append(names_in.name1.iloc[0])
elif (names_in.local_type == "City").any():
names.append(names_in[names_in.local_type == "City"].name1.str.cat(sep=' - '))
elif (names_in.local_type == "Town").any():
names.append(names_in[names_in.local_type == "Town"].name1.str.cat(sep=' - '))
elif (names_in.local_type == "Suburban Area").any():
names.append(names_in[names_in.local_type == "Suburban Area"].name1.str.cat(sep=' - '))
elif (names_in.local_type == "Village").any():
names.append(names_in[names_in.local_type == "Village"].name1.str.cat(sep=' - '))
elif (names_in.local_type == "Hamlet").any():
names.append(names_in[names_in.local_type == "Hamlet"].name1.str.cat(sep=' - '))
elif (names_in.local_type == "Other Settlement").any():
names.append(names_in[names_in.local_type == "Other Settlement"].name1.str.cat(sep=' - '))
else:
names.append(None)
settlement_boundaries["name"] = names
settlement_boundaries
| geometry | name | |
|---|---|---|
| settlement | ||
| 0 | POLYGON ((142667.472 932126.244, 142647.194 93... | Stornoway |
| 3 | POLYGON ((163950.904 40031.623, 163950.405 400... | Camborne |
| 5 | MULTIPOLYGON (((166904.881 42824.079, 166903.3... | Illogan |
| 8 | POLYGON ((169788.398 41575.672, 169777.856 415... | Redruth |
| 10 | POLYGON ((175581.974 54311.766, 175582.008 543... | Perranporth |
| ... | ... | ... |
| 8968 | POLYGON ((501071.199 203479.014, 501071.401 20... | Bovingdon |
| 8996 | POLYGON ((504988.264 302841.508, 504992.439 30... | Wittering |
| 9059 | POLYGON ((515161.410 416170.202, 515161.543 41... | None |
| 9230 | POLYGON ((560071.598 165353.771, 560073.233 16... | New Ash Green |
| 9273 | POLYGON ((584270.281 332038.541, 584270.333 33... | Wicken Green Village |
1206 rows × 2 columns
settlement_boundaries = settlement_boundaries.join(areas_sorted)
settlement_boundaries.loc[areas_sorted.index, "rank"] = range(len(settlement_boundaries))
def get_level(row):
for i, val in enumerate(row, 1):
if val > 0:
return i
settlement_boundaries["level"] = settlement_boundaries.iloc[:, 3:-1].apply(get_level, axis=1)
settlement_boundaries.sort_values('rank')
| geometry | name | area | Hyper concentrated urbanity | Concentrated urbanity | Metropolitan urbanity | Regional urbanity | Local urbanity | Dense urban neighbourhoods | Gridded residential quarters | Dense residential neighbourhoods | Connected residential neighbourhoods | Accessible suburbia | Disconnected suburbia | Open sprawl | Warehouse/Park land | rank | level | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| settlement | ||||||||||||||||||
| 1845 | MULTIPOLYGON (((501683.158 157433.012, 501682.... | City of Westminster - London - City of London | 1742.303086 | 1.306332e+06 | 7.884144e+06 | 1.321113e+07 | 3.960246e+07 | 1.155779e+08 | 2.201192e+08 | 6.699935e+06 | 2.235081e+08 | 1.364017e+08 | 2.132323e+08 | 8.389185e+07 | 2.989552e+08 | 3.819127e+08 | 0.0 | 1 |
| 876 | MULTIPOLYGON (((389083.539 282798.245, 389082.... | Birmingham - Wolverhampton | 727.366923 | 0.000000e+00 | 0.000000e+00 | 1.075760e+06 | 2.806010e+06 | 5.745378e+06 | 2.758493e+07 | 1.721331e+05 | 4.842811e+07 | 4.149977e+07 | 6.251046e+07 | 5.417000e+07 | 1.447718e+08 | 3.386026e+08 | 1.0 | 3 |
| 389 | MULTIPOLYGON (((316868.400 667252.163, 316862.... | Edinburgh | 134.093444 | 0.000000e+00 | 0.000000e+00 | 6.359560e+05 | 7.521293e+06 | 7.460783e+06 | 9.309406e+06 | 1.394896e+06 | 2.096403e+07 | 1.544039e+07 | 2.041219e+07 | 8.596605e+05 | 3.194950e+07 | 1.814534e+07 | 2.0 | 3 |
| 89 | MULTIPOLYGON (((248116.901 660962.889, 248117.... | Glasgow | 424.748668 | 0.000000e+00 | 0.000000e+00 | 6.071265e+05 | 6.881265e+06 | 1.262601e+07 | 1.710456e+07 | 1.253209e+06 | 3.929345e+07 | 4.141944e+07 | 7.314527e+07 | 3.987755e+06 | 1.679558e+08 | 6.047482e+07 | 3.0 | 3 |
| 407 | MULTIPOLYGON (((329043.772 386171.162, 329042.... | Liverpool - Manchester - Salford | 1407.816751 | 0.000000e+00 | 0.000000e+00 | 5.156702e+05 | 3.950296e+06 | 7.917305e+06 | 5.427237e+07 | 3.914361e+07 | 1.443043e+08 | 8.382661e+07 | 1.885914e+08 | 3.735568e+07 | 5.668694e+08 | 2.810701e+08 | 4.0 | 3 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8150 | POLYGON ((312936.898 211049.775, 312936.408 21... | None | 0.026621 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.662141e+04 | 1201.0 | 13 |
| 7967 | POLYGON ((224900.071 675436.621, 224900.547 67... | None | 0.025772 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.577238e+04 | 1202.0 | 13 |
| 9059 | POLYGON ((515161.410 416170.202, 515161.543 41... | None | 0.015553 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.555250e+04 | 1203.0 | 13 |
| 8161 | POLYGON ((314695.924 202755.247, 314695.871 20... | None | 0.012935 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.293481e+04 | 1204.0 | 13 |
| 8136 | POLYGON ((308157.203 194986.868, 308157.930 19... | Abercynon | 0.002138 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 2.137823e+03 | 1205.0 | 13 |
1206 rows × 18 columns
settlement_boundaries.to_parquet("./settlement_boundaries.parquet")
/opt/conda/envs/gds/lib/python3.9/site-packages/pyarrow/pandas_compat.py:373: FutureWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
if _pandas_api.is_sparse(col):
settlement_boundaries["area"] = settlement_boundaries.area / 1000000
fua = gpd.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/fua.pq")
ttwa = gpd.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa.pq")
m = settlement_boundaries.set_geometry(settlement_boundaries.simplify(100)).explore(tiles="CartoDB positron")
fua.explore(m=m, color='red')
Make this Notebook Trusted to load map: File -> Trust Notebook
bds_plot = settlement_boundaries.set_geometry(settlement_boundaries.simplify(100)).to_crs(3857)
fua_plot = fua.to_crs(3857)
ttwa.explore(tiles="cartodb voyager")
Make this Notebook Trusted to load map: File -> Trust Notebook
tiles = cx.providers.CartoDB.Positron
tiles_labels = cx.providers.CartoDB.PositronOnlyLabels
from matplotlib.patches import Patch
ax = bds_plot.plot(color=ugg.COLORS[1], figsize=(10, 10), zorder=10, alpha=.8)
# bds_plot.boundary.plot(ax=ax, color=ugg.COLORS[0], linewidth=.75)
fua_plot.plot(ax=ax, alpha=.7, color=ugg.COLORS[4])
# fua_plot.boundary.plot(ax=ax, alpha=1, color=ugg.COLORS[4], linewidth=1)
fua_plot.boundary.plot(ax=ax, alpha=1, color=ugg.COLORS[0], linewidth=.8)
ax.set_ylim(6400000, 7250000)
ax.set_xlim(-650000, 220000)
ax.set_axis_off()
cx.add_basemap(ax=ax, source=tiles.build_url(scale_factor="@2x"), attribution=tiles.attribution)
legend_elements = [
Patch(facecolor=ugg.COLORS[1], label='Settlement area'),
Patch(facecolor=ugg.COLORS[4], alpha=.7, edgecolor=ugg.COLORS[0], linewidth=.8, label='Functional urban area'),
]
ax.legend(handles=legend_elements, loc='upper right', frameon=False)
scalebar = ScaleBar(dx=1,
color=ugg.COLORS[0],
location='lower right',
height_fraction=0.002,
pad=.5,
frameon=False,
)
ax.add_artist(scalebar)
plt.savefig("figs/overlay_set_fua.png", dpi=144, bbox_inches="tight")
ax = bds_plot.plot(color=ugg.COLORS[1], figsize=(10, 10), zorder=10, alpha=.8)
bds_plot.boundary.plot(ax=ax, color=ugg.COLORS[0], linewidth=.75)
# fua_plot.plot(ax=ax, alpha=.7, color=ugg.COLORS[4])
ax.set_ylim(7470000, 7600000)
ax.set_xlim(-550000, -300000)
ax.set_axis_off()
cx.add_basemap(ax=ax, source=tiles.build_url(scale_factor="@2x"), attribution=tiles.attribution)
legend_elements = [
Patch(facecolor=ugg.COLORS[1], label='Settlement area'),
]
ax.legend(handles=legend_elements, loc='upper left', frameon=True)
scalebar = ScaleBar(dx=1,
color=ugg.COLORS[0],
location='lower right',
height_fraction=0.002,
pad=.5,
frameon=False,
)
ax.add_artist(scalebar)
plt.savefig("figs/settlements_scotland.png", dpi=144, bbox_inches="tight")
ugg.CMAP
from_list
under
bad
over
fua.area.max() / 1000000
6605.0
settlement_boundaries
| geometry | name | area | |
|---|---|---|---|
| settlement | |||
| 0 | POLYGON Z ((142667.472 932126.244 0.000, 14264... | Stornoway | 1.726063 |
| 3 | POLYGON Z ((163950.904 40031.623 0.000, 163950... | Camborne | 3.282427 |
| 5 | POLYGON Z ((167036.075 42671.447 0.000, 167034... | Illogan | 0.593929 |
| 8 | POLYGON Z ((169788.398 41575.672 0.000, 169777... | Redruth | 2.543934 |
| 10 | POLYGON Z ((175581.974 54311.766 0.000, 175582... | Perranporth | 0.383067 |
| ... | ... | ... | ... |
| 9497 | POLYGON Z ((501071.199 203479.014 0.000, 50107... | Bovingdon | 0.298797 |
| 9526 | POLYGON Z ((504988.264 302841.508 0.000, 50499... | Wittering | 0.444567 |
| 9592 | POLYGON Z ((515161.410 416170.202 0.000, 51516... | None | 0.015553 |
| 9777 | POLYGON Z ((560071.598 165353.771 0.000, 56007... | New Ash Green | 0.644549 |
| 9822 | POLYGON Z ((584270.281 332038.541 0.000, 58427... | Wicken Green Village | 0.066374 |
1208 rows × 3 columns
(settlement_boundaries['area'] < 1).sum()
584
settlement_boundaries.loc[[5271]].explore()
Make this Notebook Trusted to load map: File -> Trust Notebook
areas_sorted["name"] = settlement_boundaries["name"]
plot_data = areas_sorted.set_index("name", drop=True)
plot_data.index.name = "Settlement"
plot_data.columns.name = "Signature type"
plt.subplots(figsize=(16, 4))
ax = sns.heatmap(data=plot_data.T, norm=LogNorm(), cmap="cividis_r")
plt.tick_params(
axis='x',
which='both',
bottom=False,
top=False,
labelbottom=False)
plt.savefig("hierarchy.pdf")
plot_data.index[12:20]
Index(['Plymouth', 'Sunderland - Newcastle upon Tyne', 'Aberdeen',
'Nottingham', 'Norwich', 'Scarborough',
'Skelton - Saltburn-by-the-Sea - Brotton - Marske-by-the-Sea - Redcar - Yarm - Thornaby-on-Tees - Stockton-on-Tees - Billingham - Middlesbrough - Hartlepool',
'Abertawe'],
dtype='object', name='Settlement')
plot_data.index[1040:1045]
Index(['Coundon', 'New Ash Green', 'Hamble-le-Rice', None, 'Long Buckby'], dtype='object', name='Settlement')
settlement_sig_area = with_names.groupby(["settlement", "signature_type"])["area"].sum()
settlement_sig_area.xs("Accessible suburbia", level=1)
settlement
0 9.843275e+04
3 1.941262e+05
5 9.879056e+03
8 1.610704e+05
10 6.876061e+03
...
2759 2.782918e+05
2760 7.113730e+05
2761 3.394846e+06
2762 7.550956e+06
2765 2.403334e+04
Name: area, Length: 857, dtype: float64
settlement_boundaries.assign(sig_area=settlement_sig_area.xs("Gridded residential quarters", level=1) / settlement_boundaries.area).plot("sig_area", figsize=(20, 20), scheme="quantiles", k=10s).set_axis_off()
settlement_boundaries.assign(sig_area=settlement_sig_area.xs("Dense urban neighbourhoods", level=1) / settlement_boundaries.area).plot("sig_area", figsize=(20, 20), scheme="quantiles", k=10).set_axis_off()
with_names.groupby(["signature_type"])["area"].sum().sort_values() / 1000000
signature_type
Hyper concentrated urbanity 1.306332
Concentrated urbanity 7.884144
Metropolitan urbanity 16.523881
Regional urbanity 76.432434
Local urbanity 231.114682
Gridded residential quarters 260.548485
Connected residential neighbourhoods 564.556224
Dense urban neighbourhoods 570.643221
Disconnected suburbia 698.800932
Dense residential neighbourhoods 956.964941
Accessible suburbia 2194.269106
Warehouse/Park land 2441.457800
Open sprawl 4968.897217
Name: area, dtype: float64